/*
    <one line to give the library's name and an idea of what it does.>
    Copyright (C) 2015  <copyright holder> <email>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/


#include "beep.h"
typedef struct Note_
{
	int pitch; 
	int dimation;
}Note;
// 1			2		3		 4 			5	  		6       7
// C 			D	 	E	 	 F	 	 	G	 		A	 	B
//261.6256	293.6648   329.6276 349.2282   391.9954		440		493.8833
#define BIG_D
#define PCLK 0x4200000
//C大调
#ifdef BIG_C
#define DO 262
#define RE 294
#define MI 330
#define FA 349
#define SOL 392
#define LA  440
#define SI  494
#define TIME 6000
#endif
 
 //D大调
#ifdef BIG_D
#define DO 293
#define RE 330
#define MI 370
#define FA 349
#define SOL 440
#define LA  494
#define SI  554
#define TIME 6000
#endif

Note MumIsTheBestInTheWorld[]={
	//6.	  		  //_5		 //3		 //5	
	{LA,TIME+TIME/2}, {SOL,TIME/2},{MI,TIME},{SOL,TIME},

	//1^		   //6_		  //_5		//6-
	{DO*2,TIME},{LA,TIME/2},{SOL,TIME/2} ,{LA,2*TIME},
	// 3      //5_		//_6		   //5
	{MI,TIME},{SOL,TIME/2},{LA,TIME/2},{SOL,TIME},
	// 3	 	//1_		//_6,
	{MI,TIME},{DO,TIME/2},{LA/2,TIME/2},
	//5_		//_3		//2-		   //2.
	{SOL,TIME/2},{MI,TIME/2},{RE,TIME*2},{RE,TIME+TIME/2},
	//_3 	//5			//5_			//_6
	{MI,TIME/2},{SOL,TIME},{SOL,TIME/2},{LA,TIME/2},
	// 3		//2			//1-			//5.
	{MI,TIME},{RE,TIME},{DO,TIME*2},{SOL,TIME+TIME/2},
	//_3		//2_		//_1 		//6,_
	{MI,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME/2},
	//_1		//5,--
	{DO,TIME/2},{SOL/2,TIME*3}

};
beep::beep(string file)
{
	device_file = file;
	fd = -1;
}

beep::~beep()
{
	beep_close();
}
void beep::beep_open()
{
	fd = open(device_file.c_str() , O_RDWR | O_NONBLOCK);  //打开蜂鸣器的设备文件
	if (fd < 0)    //打开失败
	{   
		perror("open pwm_buzzer device");
		exit(1);
	}
}
void beep::beep_close()
{
	if (fd >= 0) 
	{
		ioctl(fd, PWM_IOCTL_STOP);   //停止蜂鸣器
		close(fd);                   //关闭设备驱动程序文件
		fd = -1;
	}
}
void beep::beep_stop()
{
	int ret = ioctl(fd, PWM_IOCTL_STOP);  //关闭蜂鸣器
	if(ret < 0)
	{                                     //如果无法关闭蜂鸣器
		perror("stop the buzzer");
		exit(1);
	}
}
void beep::beep_freq_seting(unsigned int freq)
{
	// this IOCTL command is the key to set frequency
	int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, freq);   //设置蜂鸣器的频率
	if(ret < 0) 
	{    //如果设置出错
		perror("set the frequency of the buzzer");
		exit(1);
	}
}
void beep::beep_ring(unsigned int ms)
{
	beep_freq_seting(100);
	usleep(1000*ms);
	beep_stop();
}
void beep::beep_ring(unsigned freq, unsigned int ms)
{
	beep_freq_seting(freq);
	usleep(ms);
	beep_stop();
}
void beep::beep_music()
{
	unsigned int i = 0;
	unsigned int div;
	for(i = 0;i < sizeof(MumIsTheBestInTheWorld)/sizeof(Note);i++ )
	{
		div = (PCLK/256/4)/(MumIsTheBestInTheWorld[i].pitch);
		int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, div);   //设置蜂鸣器的频率
		if(ret < 0) {    //如果设置出错
			perror("set the frequency of the buzzer");
			exit(1);
		}
		usleep(MumIsTheBestInTheWorld[i].dimation * 50); 
		beep_stop();
	}
}
#if 0
int main(int argc,char** argv)
{
	unsigned int b = (unsigned int)(argv[1]);
	beep buzzer("/dev/buzzer");
	buzzer.beep_open();
//	buzzer.beep_ring(b,1000*500);
//	buzzer.beep_music();
//	sleep(1);
	buzzer.beep_ring(500);
	buzzer.beep_close();
	
	return 0;
}
#endif


